deal with ignoreinode config setting
authorJoey Hess <joeyh@joeyh.name>
Fri, 16 Sep 2022 18:11:25 +0000 (14:11 -0400)
committerJoey Hess <joeyh@joeyh.name>
Fri, 16 Sep 2022 18:11:25 +0000 (14:11 -0400)
Improve handling of directory special remotes with importtree=yes whose
ignoreinode setting has been changed. (By either enableremote or by
upgrading to commit 3e2f1f73cbc5fc10475745b3c3133267bd1850a7.)

When getting a file from such a remote, accept the content that would have
been accepted with the previous ignoreinode setting.

After a change to ignoreinode, importing a tree from the remote will
re-import and generate new content identifiers using the new config. So
when ignoreinode has changed to no, the inodes will be learned, and after
that point, a change in an inode will be detected as a change. Before
re-importing, a change in an inode will be ignored, as it was before the
ignoreinode change. This seems acceptble, because the user can re-import
immediately if they urgently need to add inodes. And if not, they'll
do it sometime, presumably, and the change will take effect then.

Sponsored-by: Erik Bjäreholt on Patreon
CHANGELOG
Remote/Directory.hs
Utility/InodeCache.hs
doc/bugs/Incorrect___34__file_content_has_changed__34___on_duplicates/comment_3_a99df351ed700f908b6aaf3f52d245b4._comment [new file with mode: 0644]

index 289199927bc81739aa435605767958e8a708a235..6c6f009293735478965c5666b2633a03fdab3e1a 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,6 +13,10 @@ git-annex (10.20220823) UNRELEASED; urgency=medium
     all keys via --all or in a bare repo.
     (Introduced in version 8.20200720)
   * vicfg: Include mincopies configuration.
+  * Improve handling of directory special remotes with importtree=yes whose
+    ignoreinode setting has been changed. When getting a file from such a
+    remote, accept the content that would have been accepted with the
+    previous ignoreinode setting.
 
  -- Joey Hess <id@joeyh.name>  Mon, 29 Aug 2022 15:03:04 -0400
 
index db3cc8122d2b43b7f70b8ac72d09601e3ce12e4e..5141e6a8f83696f7ffc50dd10efb1d8b1693dfd5 100644 (file)
@@ -390,10 +390,24 @@ mkContentIdentifier (IgnoreInodes ii) f st =
                        then toInodeCache' noTSDelta f st 0
                        else toInodeCache noTSDelta f st
 
+-- Since ignoreinodes can be changed by enableremote, and since previous
+-- versions of git-annex ignored inodes by default, treat two content
+-- idenfiers as the same if they differ only by one having the inode
+-- ignored.
 guardSameContentIdentifiers :: a -> ContentIdentifier -> Maybe ContentIdentifier -> a
-guardSameContentIdentifiers cont old new
-       | new == Just old = cont
+guardSameContentIdentifiers _ _ Nothing = giveup "file not found"
+guardSameContentIdentifiers cont old (Just new)
+       | new == old = cont
+       | ignoreinode new == old = cont
+       | new == ignoreinode old = cont
        | otherwise = giveup "file content has changed"
+  where
+       ignoreinode cid@(ContentIdentifier b) = 
+               case readInodeCache (decodeBS b) of
+                       Nothing -> cid
+                       Just ic -> 
+                               let ic' = replaceInode 0 ic
+                               in ContentIdentifier (encodeBS (showInodeCache ic'))
 
 importKeyM :: IgnoreInodes -> RawFilePath -> ExportLocation -> ContentIdentifier -> ByteSize -> MeterUpdate -> Annex (Maybe Key)
 importKeyM ii dir loc cid sz p = do
index 28e6b0f0dcc6133ad2e4e8873a73ed8637a8da1b..27ee0b2cc38a71a15984349efc7853a955c104e6 100644 (file)
@@ -32,6 +32,7 @@ module Utility.InodeCache (
        inodeCacheToMtime,
        inodeCacheToEpochTime,
        inodeCacheEpochTimeRange,
+       replaceInode,
 
        SentinalFile(..),
        SentinalStatus(..),
@@ -125,6 +126,10 @@ inodeCacheEpochTimeRange i =
        let t = inodeCacheToEpochTime i
        in (t-1, t+1)
 
+replaceInode :: FileID -> InodeCache -> InodeCache
+replaceInode inode (InodeCache (InodeCachePrim _ sz mtime)) =
+       InodeCache (InodeCachePrim inode sz mtime)
+
 {- For backwards compatability, support low-res mtime with no
  - fractional seconds. -}
 data MTime = MTimeLowRes EpochTime | MTimeHighRes POSIXTime
diff --git a/doc/bugs/Incorrect___34__file_content_has_changed__34___on_duplicates/comment_3_a99df351ed700f908b6aaf3f52d245b4._comment b/doc/bugs/Incorrect___34__file_content_has_changed__34___on_duplicates/comment_3_a99df351ed700f908b6aaf3f52d245b4._comment
new file mode 100644 (file)
index 0000000..ed50e89
--- /dev/null
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2022-09-16T17:43:38Z"
+ content="""
+I've made the directory special remote treat content identifiers
+that differ only in one having the inode set to 0. Which will avoid it
+failing in the situation I showed.
+"""]]